package com.zjstudio.gitee5j.controller;

import com.gitee.sdk.gitee5j.JSON;
import com.gitee.sdk.gitee5j.api.RepositoriesApi;
import com.gitee.sdk.gitee5j.model.CommitContent;
import com.gitee.sdk.gitee5j.model.ContentBasic;
import com.gitee.sdk.gitee5j.model.ContentsPathBody;
import com.gitee.sdk.gitee5j.model.ContentsPathBody1;
import com.gitee.sdk.gitee5j.model.GitUserBasic;
import com.google.gson.reflect.TypeToken;
import com.zjstudio.gitee5j.config.GiteeAccountConfig;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.Base64;

@RestController
@CrossOrigin(origins = "*")
@RequestMapping("api")
public class GiteeApiController {

    private final RepositoriesApi api = new RepositoriesApi();
    String owner = GiteeAccountConfig.USER;
    String repo = GiteeAccountConfig.USER_REPO;
    String path = GiteeAccountConfig.FILE_PATH;
    String ref = GiteeAccountConfig.USER_BRANCH;

    /**
     * 接收文本文件数据
     *
     * @param file json文件
     * @return 状态码
     */
    @PostMapping("add")
    public Integer addJSON(@RequestParam("file") MultipartFile file) {
        try {
            // 检查是否存在
            String content = this.getJSON();
            if(content == null) {
                // 不存在则新增
                content = this.getFileContent(file);
                this.postReposOwnerRepoContentsPath(content);
            }else {
                // 存在则更新
                String sha = getFileSha();
                content = this.getFileContent(file);

                ContentsPathBody body = new ContentsPathBody();
                body.setBranch(ref);
                body.setSha(sha);
                body.setContent(Base64.getEncoder().encodeToString(content.getBytes()));
                body.setMessage(GiteeAccountConfig.MSG);
                CommitContent response = api.putReposOwnerRepoContentsPath(owner, repo, path, body);
                System.out.println("update file response : " + response);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 500;
        }
        return 200;
    }

    /**
     * 获取文件内容
     */
    @GetMapping("get")
    public String getJSON() {
        try {
            return this.getReposOwnerRepoRawPath();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取文件
     * @return
     * @throws Exception
     */
    public String getReposOwnerRepoRawPath() throws Exception {
        File response = api.getReposOwnerRepoRawPath(owner, repo, path, ref);
        System.out.println("get file response : "+response);
        return fileToString(response);

    }

    public static String fileToString(File file) {
        StringBuilder content = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = br.readLine())!= null) {
                content.append(line).append("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return content.toString();
    }

    /**
     * @param file
     * @return MultipartFile 转 String
     * @throws IOException
     */
    private String getFileContent(MultipartFile file) throws IOException {
        // 读取文件内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
        String line;
        StringBuilder content = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            content.append(line);
        }
        reader.close();
        return content.toString();
    }

    /**
     * 添加文件
     * @param content 文件内容
     * @throws Exception
     */
    public void postReposOwnerRepoContentsPath(String content) throws Exception {

        GitUserBasic gitUser = new GitUserBasic();
        gitUser.setEmail(GiteeAccountConfig.EMAIL);
        gitUser.setName(GiteeAccountConfig.USERNAME);

        // 先删除
//        ContentsPathBody2 body2 = new ContentsPathBody2();
//        body2.setBranch(GiteeAccountConfig.USER_BRANCH);
//        body2.setSha(response.getContent().getSha());
//        body2.setMessage("delete file " + path);
//        api.deleteReposOwnerRepoContentsPath(owner, repo, path, body2);

        ContentsPathBody1 body = new ContentsPathBody1();
        body.setContent(Base64.getEncoder().encodeToString(content.getBytes()));
        body.setBranch(GiteeAccountConfig.USER_BRANCH);
        body.setMessage(GiteeAccountConfig.MSG);
        body.setAuthor(gitUser);
        body.setCommitter(gitUser);

        CommitContent response = api.postReposOwnerRepoContentsPath(owner, repo, path, body);
        System.out.println("add file response : " + response);
    }


    private String getFileSha() throws IOException {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://gitee.com/api/v5/repos/" + owner + "/" + repo + "/contents/" + path)
                .addHeader("Authorization", "token " + GiteeAccountConfig.ACCESS_TOKEN)
                .build();
        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                String json = response.body().string();
//                ObjectMapper objectMapper = new ObjectMapper();
//                GiteeFileContent commitContent = objectMapper.readValue(json, GiteeFileContent.class);
                Type localVarReturnType = new TypeToken<ContentBasic>() {
                }.getType();
                JSON jsonObj = new JSON();
                ContentBasic contentBasic = jsonObj.deserialize(json, localVarReturnType);
                return contentBasic.getSha();
            } else {
                return null;
            }
        }
    }

}
